package com.hao.link;

/**
 * TODO
 *
 * @author 97472
 * @version 1.0
 * @date 2021/4/20 14:48
 */
public class MyRingSingLinkList<T> implements MyLinkList<T>{
    /**
     * 第一个节点
     */
    private Node<T> firstNode;
    /**
     * 链表的大小
     */
    private Integer size = 0;
    public void add(T t) {
        Node<T> newNode = new Node(t, null);
        boolean hasFirstNode = firstNode !=null;
        if (hasFirstNode){
            Node<T> lastNode = getLastNode();
            lastNode.nextNode = newNode;
            newNode.nextNode = firstNode;
        }else {
            firstNode = newNode;
            firstNode.nextNode = firstNode;
        }
        size++;
    }

    public void delete(int index) {
        isOut(index);
        if (index == 0){
            if (size == 1){
                firstNode = null;
            }else {
                Node<T> temp = firstNode;
                firstNode = temp.nextNode;
                temp.nextNode = null;
                getLastNode().nextNode = firstNode;
            }
        }else {
            Node<T> delBeforeNode = getBeforeByIndex(index);
            Node<T> delNode = delBeforeNode.nextNode;
            delBeforeNode.nextNode = delNode.nextNode;
            delNode.nextNode = null;
        }
        size--;
    }

    public void update(int index, T t) {
        isOut(index);
        if (index == 0){
            delete(0);
            add(t);
        }else {
            Node update = new Node(t, null);
            Node<T> beforeNode = getBeforeByIndex(index);
            Node<T> updateNode = beforeNode.nextNode;
            beforeNode.nextNode = update;
            update.nextNode = updateNode.nextNode;
            updateNode.nextNode = null;
        }
    }

    public void insert(int index, T t) {
        isOut(index);
        Node insertNode = new Node(t, null);
        if (index == 0){
            Node<T> lastNode = getLastNode();
            insertNode.nextNode = firstNode;
            firstNode = insertNode;
            lastNode.nextNode = firstNode;
        }else {
            Node<T> beforeNode = getBeforeByIndex(index);
            Node<T> nextNode = beforeNode.nextNode;
            beforeNode.nextNode = insertNode;
            insertNode.nextNode = nextNode;
        }
        size++;
    }

    public T get(int index) {
        return getBeforeByIndex(index).nextNode.t;
    }

    public Integer size() {
        return null;
    }

    public Boolean isEmpty() {
        return null;
    }
    private Node<T> getLastNode(){
        if (firstNode == null){
            return null;
        }
        Node<T> lastNode = firstNode;
        boolean hastNext = true;
        while (hastNext){
            lastNode = lastNode.nextNode;
            hastNext = lastNode.nextNode != firstNode;
        }
        return lastNode;
    }
    private Node<T> getBeforeByIndex(int index){
        isOut(index);
        Node<T> temp = firstNode;
        for (int i = 0; i < index-1; i++) {
            temp = temp.nextNode;
        }
        return temp;
    }
    private void isOut(int index){
        boolean isOut = index >= size || index < 0;
        if (isOut){
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    @Override
    public String toString() {
        String out = "";
        Node<T> temp = firstNode;
        for (int i = 0; i < size; i++) {
            out = out + "  " + temp.t;
            temp = temp.nextNode;
        }
        return out;
    }
    /**
     * @Author a'hao
     * @Description //TODO 这是链表的节点
     * @Date 16:56 2021/4/18
     * @Param
     * @return
     **/
    class Node<T>{
        /**
         * @Author a'hao
         * @Description //TODO 用户要存放的数据
         * @Date 16:57 2021/4/18
         * @Param
         * @return
         **/
        private T t;
        /**
         * @Author a'hao
         * @Description //TODO 下一个节点的地址
         * @Date 16:58 2021/4/18
         * @Param
         * @return
         **/
        private Node<T> nextNode;

        public Node(T t, Node<T> nextNode) {
            this.t = t;
            this.nextNode = nextNode;
        }

    }
}
